package com.zikao.question.controller;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zikao.common.exception.RRException;
import com.zikao.common.vo.TableListVo;
import com.zikao.question.entity.*;
import com.zikao.question.service.*;
import com.zikao.user.entity.UserEntity;
import com.zikao.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import com.zikao.common.utils.PageUtils;
import com.zikao.common.utils.R;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @author likaisheng
 * @email 1805318928@qq.com
 * @date 2021-03-03 20:46:00
 */
@Slf4j
@Controller
@RequestMapping("question/question")
public class QuestionController {
    @Autowired
    private QuestionService questionService;
    @Autowired
    private Text2Service text2Service;
    @Autowired
    private AnswerService answerService;
    @Autowired
    private UserService userService;
    @Autowired
    private Tag2Service tag2Service;
    @Autowired
    private Praise2Service praise2Service;
    @Autowired
    private Collect2Service collect2Service;

    @RequestMapping("/showQuestion/{id}")
    public String showQuestion(@PathVariable("id") Long id, Model model) {
        List<AnswerEntity> answers = null;

        try {
            // 获取点赞数
            QueryWrapper<Praise2Entity> praisewrapper = new QueryWrapper<>();
            praisewrapper.eq("question_id", id);
            int praiseNum = praise2Service.count(praisewrapper);
            // 获取收藏数
            QueryWrapper<Collect2Entity> collectwrapper = new QueryWrapper<>();
            collectwrapper.eq("question_id", id);
            int collectNum = collect2Service.count(collectwrapper);
            // 获取答案数
            QueryWrapper<AnswerEntity> remarkwrapper = new QueryWrapper<>();
            remarkwrapper.eq("question_id",id);
            int answerNum = answerService.count(remarkwrapper);

            // 获取问题
            QuestionEntity question = questionService.getById(id);

            // 获取问题的答案
            Map<String, Object> answerMap = new HashMap<>();
            answerMap.put("question_id", id);
            answers = answerService.selectByMap(answerMap);
            if (answers.size() > 0){
                List<Long> userIds = answers.stream().map(r -> {
                    return r.getUserId();
                }).collect(Collectors.toList());
                List<UserEntity> userList = userService.selectBatchIds(userIds);
                Map<Long, UserEntity> userMap = userList.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));

                // 获取答案的内容
                if (answers.size() > 0) {
                    List<Long> textIds = answers.stream().map(r -> {
                        return r.getTextId();
                    }).collect(Collectors.toList());
                    List<Text2Entity> texts = text2Service.selectBatchIds(textIds);
                    Map<Long, Text2Entity> textMap = texts.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));

                    for (AnswerEntity answer : answers) {
                        String content = textMap.get(answer.getTextId()).getContent();
                        UserEntity user = userMap.get(answer.getUserId());
                        answer.setContent(content);
                        answer.setUserName(user.getName());
                    }
                }
            }

            model.addAttribute("questionUserId", question.getUserId());
            model.addAttribute("questionId", id);
            model.addAttribute("status",question.getStatus());
            model.addAttribute("answers", answers);
            model.addAttribute("praiseNum", praiseNum);
            model.addAttribute("collectNum", collectNum);
            model.addAttribute("answerNum", answerNum);
        } catch (Exception e) {
            log.error("程序出现错误-showArticle", e);
            throw new RRException("程序出现错误，请联系管理员", 500);
        }
        return "showQuestion";
    }

    /**
     * 获取今日推荐列表
     * 按今日浏览选择10个问题
     */
    @RequestMapping("/recommends")
    @ResponseBody
    public List<QuestionEntity> recommends(@RequestParam Map<String, Object> params) {
        List<QuestionEntity> questionList = null;
        try {
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.gt("pv", 0);
            wrapper.orderByDesc("pv");
            wrapper.last("limit 10");
            questionList = questionService.selectList(wrapper);
        } catch (Exception e) {
            log.error("程序发生错误-recommends", e);
            throw new RRException("程序发生错误", 500);
        }
        return questionList;
    }

    /**
     * 获取热门问答列表
     * 按总浏览量选10篇
     */
    @RequestMapping("/hots")
    @ResponseBody
    public List<QuestionEntity> hots(@RequestParam Map<String, Object> params) {
        List<QuestionEntity> questionList = null;
        try {
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.orderByDesc("total_pv");
            wrapper.last("limit 10");
            questionList = questionService.selectList(wrapper);
        } catch (Exception e) {
            log.error("程序发生错误-recommends", e);
            throw new RRException("程序发生错误", 500);
        }
        return questionList;
    }

    @RequestMapping("/toQuestionPage")
    public String toQuestionPage(Model model) {
        Map<String, Object> params = new HashMap<>();
        List<QuestionEntity> questions = questionService.selectByMap(params);

        List<Long> textIds = questions.stream().map(r -> {
            return r.getTextId();
        }).collect(Collectors.toList());
        List<Text2Entity> texts = text2Service.selectBatchIds(textIds);
        Map<Long, Text2Entity> textMap = texts.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));

        for (QuestionEntity question : questions) {
            Long textId = question.getTextId();
            Text2Entity text = textMap.get(textId);
            question.setContent(text.getContent());
        }

        List<Tag2Entity> tag2List = tag2Service.selectByMap(new HashMap<>());
        model.addAttribute("questions", questions);
        model.addAttribute("curPage", "question");
        model.addAttribute("tags", tag2List);
        return "question";
    }

    /**
     * 列表 for layui
     * 用于显示问题列表
     * 注意这两个注解的使用 @RequestBody @RequestParam
     */
    @RequestMapping("/listForLayUI")
    @ResponseBody
    public TableListVo listForLayUI(@RequestBody Map<String, Object> params) {
        TableListVo<QuestionEntity> tableListVo = new TableListVo();

        try {
            // 处理搜索功能
            String searchStr = (String) params.get("searchStr");
            QueryWrapper<QuestionEntity> queryWrapper = new QueryWrapper<>();
            if (StringUtils.isNotBlank(searchStr)) {
                // 处理搜索框输入
                // 按照空格截取字符串
                String[] strArr = searchStr.split(" ");
                for (int i = 0; i < strArr.length - 1; i++) {
                    queryWrapper.like("title", strArr[i]);
                    queryWrapper.or();
                }
                queryWrapper.like("title", strArr[strArr.length - 1]);
            }

            // 是否传入了用户id
            String userIdStr = (String) params.get("userId");
            if (StringUtils.isNotBlank(userIdStr)) {
                Long userId = Long.parseLong(userIdStr);
                queryWrapper.eq("user_id", userId);
            }

            // 处理问题标签
            String tagIdStr = (String) params.get("tagId");
            if (StringUtils.isNotBlank(tagIdStr)) {
                Long tagId = Long.parseLong(tagIdStr);
                queryWrapper.eq("tag_id", tagId);
            }

            // 处理问题状态
            String statusStr = (String) params.get("status");
            if (StringUtils.isNotBlank(statusStr)) {
                Integer status = Integer.parseInt(statusStr);
                queryWrapper.eq("status", status);
            }

            // 设置按修改时间排序
            queryWrapper.orderByDesc("update_time");

            String page = params.get("page").toString();
            params.put("page", page);
            String limit = params.get("limit").toString();
            params.put("limit", limit);
            PageUtils pageUtils = questionService.queryPage(params, queryWrapper);
            tableListVo.setCode(0);
            tableListVo.setMsg("");
            tableListVo.setCount(pageUtils.getTotalCount());

            List<QuestionEntity> questionList = (List<QuestionEntity>) pageUtils.getList();
            List<Long> userIds = questionList.stream().map(r -> {
                return r.getUserId();
            }).collect(Collectors.toList());
            List<Long> textIds = questionList.stream().map(r -> {
                return r.getTextId();
            }).collect(Collectors.toList());

            if (questionList.size() > 0) {
                // 拼装用户数据
                List<UserEntity> userList = userService.selectBatchIds(userIds);
                Map<Long, UserEntity> userMap = userList.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));
                for (QuestionEntity question : questionList) {
                    UserEntity user = userMap.get(question.getUserId());
                    question.setUserName(user.getName());
                }
                // 拼装文本数据
                List<Text2Entity> textList = text2Service.selectBatchIds(textIds);
                Map<Long, Text2Entity> textMap = textList.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));
                for (QuestionEntity question : questionList) {
                    Text2Entity text = textMap.get(question.getTextId());
                    question.setContent(text.getContent());
                }
            }
            tableListVo.setData(questionList);
        } catch (Exception e) {
            log.error("程序发生错误-listForLayUI", e);
            throw new RRException("程序发生错误", 500);
        }
        return tableListVo;
    }

    /**
     * 列表 for layui
     * 用于显示问题列表
     * 注意这两个注解的使用 @RequestBody @RequestParam
     */
    @RequestMapping("/listForLayUI2")
    @ResponseBody
    public TableListVo listForLayUI2(@RequestParam Map<String, Object> params) {
        TableListVo<QuestionEntity> tableListVo = new TableListVo();

        try {
            // 处理搜索功能
            String searchStr = (String) params.get("searchStr");
            QueryWrapper<QuestionEntity> queryWrapper = new QueryWrapper<>();
            if (StringUtils.isNotBlank(searchStr)) {
                // 处理搜索框输入
                // 按照空格截取字符串
                String[] strArr = searchStr.split(" ");
                for (int i = 0; i < strArr.length - 1; i++) {
                    queryWrapper.like("title", strArr[i]);
                    queryWrapper.or();
                }
                queryWrapper.like("title", strArr[strArr.length - 1]);
            }

            // 是否传入了用户id
            String userIdStr = (String) params.get("userId");
            if (StringUtils.isNotBlank(userIdStr)) {
                Long userId = Long.parseLong(userIdStr);
                queryWrapper.eq("user_id", userId);
            }

            // 处理问题标签
            String tagIdStr = (String) params.get("tagId");
            if (StringUtils.isNotBlank(tagIdStr)) {
                Long tagId = Long.parseLong(tagIdStr);
                queryWrapper.eq("tag_id", tagId);
            }

            // 处理问题状态
            String statusStr = (String) params.get("status");
            if (StringUtils.isNotBlank(statusStr)) {
                Integer status = Integer.parseInt(statusStr);
                queryWrapper.eq("status", status);
            }

            // 设置按修改时间排序
            queryWrapper.orderByDesc("update_time");

            String page = params.get("page").toString();
            params.put("page", page);
            String limit = params.get("limit").toString();
            params.put("limit", limit);
            PageUtils pageUtils = questionService.queryPage(params, queryWrapper);
            tableListVo.setCode(0);
            tableListVo.setMsg("");
            tableListVo.setCount(pageUtils.getTotalCount());

            List<QuestionEntity> questionList = (List<QuestionEntity>) pageUtils.getList();
            List<Long> userIds = questionList.stream().map(r -> {
                return r.getUserId();
            }).collect(Collectors.toList());
            List<Long> textIds = questionList.stream().map(r -> {
                return r.getTextId();
            }).collect(Collectors.toList());

            if (questionList.size() > 0) {
                // 拼装用户数据
                List<UserEntity> userList = userService.selectBatchIds(userIds);
                Map<Long, UserEntity> userMap = userList.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));
                for (QuestionEntity question : questionList) {
                    UserEntity user = userMap.get(question.getUserId());
                    question.setUserName(user.getName());
                }
                // 拼装文本数据
                List<Text2Entity> textList = text2Service.selectBatchIds(textIds);
                Map<Long, Text2Entity> textMap = textList.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));
                for (QuestionEntity question : questionList) {
                    Text2Entity text = textMap.get(question.getTextId());
                    question.setContent(text.getContent());
                }
            }
            tableListVo.setData(questionList);
        } catch (Exception e) {
            log.error("程序发生错误-listForLayUI", e);
            throw new RRException("程序发生错误", 500);
        }
        return tableListVo;
    }

    /**
     * 统计pv
     */
    @RequestMapping("/statistics/pv/{id}")
    @ResponseBody
    public R statisticsPv(@PathVariable("id") Long id) {
        try {
            QuestionEntity question = questionService.getById(id);
            Integer curPv = Optional.ofNullable(question.getPv()).orElse(0);
            Integer curTotalPv = Optional.ofNullable(question.getTotalPv()).orElse(0);
            question.setPv(curPv + 1);
            question.setTotalPv(curTotalPv + 1);
            questionService.updateById(question);
        } catch (Exception e) {
            log.error("程序发生错误-statisticsPv:", e);
            return R.error();
        }
        return R.ok();
    }

    /**
     * 列表
     */
    @RequestMapping("/list")
    @ResponseBody
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = questionService.queryPage(params);

        return R.ok().put("page", page);
    }

    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    @ResponseBody
    public R info(@PathVariable("id") Long id) {
        // 获取问题信息
        QuestionEntity question = questionService.getById(id);
        Text2Entity text = text2Service.getById(question.getTextId());
        question.setContent(text.getContent());
        // 获取用户信息
        UserEntity user = userService.getById(question.getUserId());
        question.setUserName(user.getName());

        return R.ok().put("question", question);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    @ResponseBody
    public R save(@RequestBody QuestionEntity question, HttpServletRequest request, HttpServletResponse response) {
        UserEntity user = (UserEntity) request.getSession().getAttribute("user");
        question.setPv(0);
        question.setTotalPv(0);
        question.setUserId(user.getId());
        question.setStatus(0);

        questionService.saveQuestion(question);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @ResponseBody
    public R update(@RequestBody QuestionEntity question) {
        questionService.updateById(question);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @ResponseBody
    public R delete(@RequestBody Long[] ids) {
        questionService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }
}
